/*
The surface-physics project: http://code.google.com/p/surface-physics/
Adds real world physics based on the Bullet physics engine, to bases in the Orbiter space
flight simulation software.

Written by Abhijit Nandy
License : Apache License 2.0

Bump_TerrainPatch.h
Terrain Patch management

This file declares the Bump_TerrainPatch class.

The patch class is used as follows in objects which are in contact/affected by terrain


	The patch has the longitude and latitude limits which it covers on the surface
	Due to the spherical shape the patch area decreases as we approach the poles as the long. span remains
	same and they converge.
	These are the rules followed by objects(which are affected by terrain) :

	1.An object maintains its own supporting terrain patch
	2.Rather than maintain a terrain patch list in the base, its better to use raycasting
	   (directing it normal to the surface,else it may miss it), down from the middle of the terrain patch to
	   discover the terrain. The use the user pointer to get the terrain patch pointer, which has the triangle
	   mesh ptr and reference count. If reference count drops to 0 when a patch is invalidated, delete it.
	   Otherwise patch search time is O(N) which may be slower than raycasting in Bullet.

	3.Object has a terrain patch. The patch is updated by passing the current vehicle position wrt base.
	It will not be called if the reference body for the camera is not the object's base's ref body.
	A dynamic object will not be updated till its camera ref body = object ref body (orulex uses camera ref body).

	4.Terrain updates can be done in poststep() of object

*	5.1 terrain patch with partialRefit() and triangles added as required should be enough to support vehicle.


Note: this method is independent of direction of movement of object or planet. Its based purely on values of longitude
& latitude.






*/


#pragma once


#include "../BulletBase/Bump_BaseObject.h"


/**
 * The Bump_TerrainPatch to create and manage a supporting terrain
 */
class Bump_TerrainPatch 
{

	/* Terrain related constants */
	//Max points in 1 dimension: SHOULD BE POWER OF 2(for speed), max. quads is MAX_POINTS-1 in 1 dim
	//This is also the number of latitudes and longitudes used to get points(the points are their intersection)
	unsigned int lngMaxPoints, latMaxPoints;
	unsigned int lngMaxQuads,  latMaxQuads;

	//Total no. of quads is (MAX_POINTS-1)*(MAX_POINTS-1), 2 triangle/quad, 3 vertices per triangle.
	unsigned int maxIndices;

	//The increment amount to lola, single point precision is 7 digits, double should cover 6 digits
	double lngAngleIncr, latAngleIncr;

	double lngBorderWidth, latBorderWidth;
	double lngMidpoint, latMidpoint;
	double updateDistance;

	btVector3 *vertices;
	int *indices;

	//Vertices, collision shape and rigid body for this patch
	btTriangleIndexVertexArray*	m_indexVertexArrays;
	btBvhTriangleMeshShape* collshpTerrainPatch;
	btRigidBody* rbTerrainPatch;

	//Terrain patch coverage area on body sphere
	double equLngStart, equLngEnd, equLatStart, equLatEnd;


	//The surface point corresponding to equLngStart and equLatStart in base frame
	VECTOR3 rposSurfStartPoint;

	//Required during terrain creation and refit
	btVector3 aabbMin, aabbMax;

public:

	Bump_TerrainPatch(){};
	Bump_TerrainPatch(unsigned int lngMaxPoints, unsigned int latMaxPoints,
					  double lngAngleIncr, double latAngleIncr,
					  double lngBorder, double latBorder,
					  double updateDistance);
	virtual ~Bump_TerrainPatch();


	int createPatch(Bump_BulletBase *base, double lng, double lat);
	int updatePatch(Bump_BulletBase *base, double lng, double lat, double rad);


	//A terrain vertices function for each terrain generator available
	int setTerrainVerticesORU(Bump_BulletBase *base);

};


